package com.atguigu.gulimall.search.thread;

import org.omg.PortableServer.THREAD_POLICY_ID;

import java.util.concurrent.*;

/**
 * @Description TODO
 * @Author 鲁班爱喝旺仔
 * @Date 2020/4/18 10:36
 * @Version 1.0
 **/
public class ThreadTest {

    /**
     * 线程池的创建:
     *  1. new ThreadPollExecutor(Object...args)
     *      int corePoolSize,
     *      int maximumPoolSize,
     *      long keepAliveTime,
     *      TimeUnit unit,
     *      BlockingQueue<Runnable> workQueue,  阻塞队列, 将目前多出的任务放入进行排队
     *      ThreadFactory threadFactory,
     *      RejectedExecutionHandler handler: 如果队列慢了,按照指定的拒绝策略拒绝执行任务
     *
     *      顺序：
     *           1、先创建核心线程运行任务
     *           2、核心线程满放入阻塞队列
     *      	        new LinkedBlockingDeque()默认是Integer的最大值，
     *           3、阻塞队列满了继续创建线程，最多创建maximumPoolSize个
     *           4、如果传入了拒绝策略会执行，否则抛出异常
     *           5、拒绝策略：
     *      	        1、丢弃最老的 Rejected
     *      	        2、调用者同步调用，直接调用run方法，不创建线程了 Caller
     *      	        3、直接丢弃新任务 Abort	【默认使用这个】
     *      	        4、丢弃新任务，并且抛出异常 Discard
     *  2、常见的4种线程池
     *      1、CachedThreadPool：核心线程数是0，如果空闲会回收所有线程【缓存线程池】
     *      2、FixedThreadPool：核心线程数 = 最大线程数，【不回收】
     *      3、ScheduledThreadPool：定时任务线程池，多久之后执行【可提交核心线程数，最大线程数是Integer.Max】
     *      4、SingleThreadPool：核心与最大都只有一个【不回收】,后台从队列中获取任务
     */

    ThreadPoolExecutor executor1 = new ThreadPoolExecutor(5,
            200,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100000),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        System.out.println("main...start");
        /**
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程号 -> " + Thread.currentThread().getId());
            int n = 10 / 5;
            System.out.println("运行结果：" + n);
        }, executor); */


        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程号 -> " + Thread.currentThread().getId());
            int n = 10 / 0;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return n;
        }, executor).whenComplete((result,excption) -> {  // whenComplete只能感知异常,无法修改返回值
            System.out.println("运行结果：" + result + " 异常：" + excption);
        }).exceptionally(throwable -> {
            // exceptionally, 感知异常并修改返回值
            return 10;
        });

        Integer integer = future.get();
        System.out.println("最终运行结果：" + integer);
        System.out.println("main...end");

    }

    public static void thread(String[] args) throws ExecutionException, InterruptedException {

        System.out.println("main... start");

        /** 1、继承Thread
         */
//        Thread01 thread01 = new Thread01();
//        thread01.start();

        /** 2、实现Runnable接口
         *  没有返回值
         */
//        Runnable01 runnable01 = new Runnable01();
//        new Thread(runnable01).start();

        /** 3、实现Callable接口 + FutureTask (可以拿到返回结果，可以处理异常)
         * 阻塞等待
         */
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
        new Thread(futureTask).start();
        // 等待线程执行完获取结果
        Integer n = futureTask.get();
        System.out.println(n);

        // 线程池 --  资源控制
//        service.execute(new Runnable01());
        /**
            int corePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit unit,
            BlockingQueue<Runnable> workQueue,
            ThreadFactory threadFactory,
            RejectedExecutionHandler handler
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());


        System.out.println("main... end");

    }

    public static class Callable01 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            System.out.println("Runnable01当前线程号 -> " + Thread.currentThread().getId());
            int n = 10 /5;
            return n;
        }

    }


    public static class Runnable01 implements Runnable {
        @Override
        public void run() {
            System.out.println("Runnable01当前线程号 -> " + Thread.currentThread().getId());
            int n = 10 /5;
            System.out.println(n);
        }
    }

    public static class Thread01 extends Thread{

        @Override
        public void run() {

            System.out.println("Thread01当前线程号 -> " + Thread.currentThread().getId());
            int n = 10 /5;
            System.out.println(n);
        }
    }
}
